package com.ehome.poct.terminal.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.ehome.context.context.SpringContextHolder;
import com.ehome.core.util.BeanConvertUtil;
import com.ehome.exception.BizException;
import com.ehome.poct.terminal.api.constant.PackageType;
import com.ehome.poct.terminal.api.constant.VersionType;
import com.ehome.poct.terminal.api.dto.TestDeviceVersionDTO;
import com.ehome.poct.terminal.api.fegin.TestDeviceVersionFeginClient;
import com.ehome.poct.terminal.api.qry.CurrentSoftwareVersionQry;
import com.ehome.poct.terminal.api.qry.NewSoftwareVersionQry;
import com.ehome.poct.terminal.api.qry.NewVersionQry;
import com.ehome.poct.terminal.api.qry.UpgradeQry;
import com.ehome.poct.terminal.api.vo.NewSoftwareVersionVO;
import com.ehome.poct.terminal.api.vo.NewVersionVO;
import com.ehome.poct.terminal.mapping.UpgradeMapping;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UpgradeService {
    @Autowired
    TestDeviceVersionFeginClient testDeviceVersionFeginClient;
    @Autowired
    UpgradeMapping upgradeMapping;


    public List<NewSoftwareVersionVO> getNewDriverVersion(NewSoftwareVersionQry qry) {
        qry.setPackageType(PackageType.DRIVER.ordinal());
        return getSoftwareNewVersionVO(qry);
    }

    public NewVersionVO getNewFirmwareVersion(NewVersionQry qry) {
        qry.setPackageType(PackageType.FIRMWARE.ordinal());
        return getNewVersionVO(qry);
    }

    public List<NewSoftwareVersionVO> getNewSoftwareVersion(NewSoftwareVersionQry qry) {
        qry.setPackageType(PackageType.SOFTWARE.ordinal());
        return getSoftwareNewVersionVO(qry);
    }


    private NewVersionVO getNewVersionVO(NewVersionQry qry) {
        NewVersionVO newVersion = CollUtil.getFirst(testDeviceVersionFeginClient.getNewVersion(qry));
        UpgradeQry qry2 = new UpgradeQry();
        qry2.setProjectName(qry.getProjectName());
        qry2.setPackageType(qry.getPackageType());
        TestDeviceVersionDTO upgradeInfo = testDeviceVersionFeginClient.getUpgradeInfo(qry2);
        if (newVersion != null) {
            String version = getVersion(qry.getVersionType(), newVersion.getVersion());
            newVersion.setVersion(version);
            newVersion.setVersionCode(upgradeInfo.getVersionCode() + 1);

        } else {
            newVersion = new NewVersionVO();
            newVersion.setVersion(getVersion(VersionType.DEFAULT.ordinal(), "4.0.0"));
            if (upgradeInfo != null && upgradeInfo.getVersionCode() != null) {
                newVersion.setVersionCode(upgradeInfo.getVersionCode() + 1);
            } else {
                newVersion.setVersionCode(400);
            }
        }
        newVersion.setProjectName(qry.getProjectName());
        return newVersion;
    }

    private NewVersionVO getDefaultNewVersion(NewSoftwareVersionQry qry) {
        UpgradeQry qry2 = new UpgradeQry();
        qry2.setPackageType(qry.getPackageType());
        qry2.setPackageId(qry.getPackageId());
        TestDeviceVersionDTO upgradeInfo = testDeviceVersionFeginClient.getUpgradeInfo(qry2);
        NewVersionVO newVersion = new NewVersionVO();
        newVersion.setProjectName(qry.getProjectName());
        newVersion.setVersion(getVersion(VersionType.DEFAULT.ordinal(), "4.0.0"));
        if (upgradeInfo != null && upgradeInfo.getVersionCode() != null) {
            newVersion.setVersionCode(upgradeInfo.getVersionCode() + 1);
        } else {
            newVersion.setVersionCode(400);
        }
        return newVersion;
    }

    private List<NewSoftwareVersionVO> getSoftwareNewVersionVO(NewSoftwareVersionQry qry) {
        CurrentSoftwareVersionQry versionQry = upgradeMapping.to(qry);
        List<NewSoftwareVersionVO> newSoftwareVersion = testDeviceVersionFeginClient.getNewSoftwareVersion(versionQry);
        if (CollUtil.isNotEmpty(newSoftwareVersion)) {
            for (NewSoftwareVersionVO newVersion : newSoftwareVersion) {
                newVersion.setProjectName(qry.getProjectName());
                String version = getVersion(qry.getVersionType(), newVersion.getVersion());
                newVersion.setVersion(version);
                newVersion.setVersionCode(newVersion.getVersionCode() + 1);
            }
        } else {
            newSoftwareVersion = Lists.newArrayList();
            NewVersionVO defaultNewVersion = getDefaultNewVersion(qry);
            NewSoftwareVersionVO versionVO = BeanConvertUtil.convertBean(defaultNewVersion, NewSoftwareVersionVO.class);
            versionVO.setPackageId(qry.getPackageId());
            newSoftwareVersion.add(versionVO);
        }
        return newSoftwareVersion;
    }

    private String getVersion(Integer versionType, String version) {
        String activeProfiles = SpringContextHolder.getApplicationContext().getEnvironment().getActiveProfiles()[1];
        boolean any = StrUtil.containsAny(activeProfiles, "develop", "beta");
        boolean match = ReUtil.isMatch("\\d+(\\.\\d+){2}", version);
        if (!match && !any) {
            throw new BizException(201, "版本号格式不对");
        }

        if (any) {
            version = StrUtil.subBefore(version, "_", false);
        }

        String[] split = version.split("\\.");
        VersionType versionTypeEnum = VersionType.getVersionTypeEnum(versionType);
        switch (versionTypeEnum) {
            case ITERATION:
                split[2] = String.valueOf(Integer.valueOf(split[2]) + 1);
                break;
            case FUNCTION:
                split[1] = String.valueOf(Integer.valueOf(split[1]) + 1);
                split[2] = String.valueOf(0);
                break;
            case STAGE:
                split[0] = String.valueOf(Integer.valueOf(split[0]) + 1);
                split[1] = String.valueOf(0);
                split[2] = String.valueOf(0);
                break;
            default:
                break;
        }
        String join = String.join(".", split);
        String ver = join;
        if (any) {
            ver = StrUtil.strBuilder(join, StrUtil.UNDERLINE,
                    DateUtil.format(DateUtil.date(), "yyMMdd"),
                    StrUtil.UNDERLINE,
                    DateUtil.format(DateUtil.date(), DatePattern.PURE_TIME_PATTERN)).toString();
        }
        return ver;
    }
}
